from typing import List

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QTableWidget, QAbstractItemView, QTableWidgetItem, QMenu, QLabel

from common.equipment.reference import Equipment, EQUIPMENT_SLOTS
from common.player.reference import Player
from gui.signals import SIGNALS
from gui.widgets_map import open_window
from utils.db import DBSession
from utils.reference import message_box_information


class DoubleColView(QTableWidget):
    def __init__(self, headers: List[str]):
        super(DoubleColView, self).__init__()

        self.setColumnCount(2)
        self.setRowCount(len(headers))
        self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        self.verticalHeader().setVisible(False)
        self.horizontalHeader().setVisible(False)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.setContentsMargins(0, 0, 0, 0)
        self.setFixedHeight(30 * len(headers) + 2)
        self.setColumnWidth(0, 35)
        self.horizontalHeader().setStretchLastSection(True)
        self.setStyleSheet('QTableWidget::item{height: 30px}')

        for row, header in enumerate(headers):
            self.setItem(row, 0, QTableWidgetItem(header))


class EquipmentView(DoubleColView):
    def __init__(self, player: Player):
        super(EquipmentView, self).__init__([DBSession.tr[i] for i in EQUIPMENT_SLOTS])
        self.player = player
        self.update_data()
        self.customContextMenuRequested.connect(self.show_menu)

    def update_data(self):
        for row, equip_key in enumerate(EQUIPMENT_SLOTS):
            player_equip: Equipment = self.player.equip_slots[equip_key]
            self.setCellWidget(row, 1, QLabel('' if player_equip is None else player_equip.overview()))

    def show_menu(self, position):
        index = self.indexAt(position)
        if not index.isValid():
            return

        menu = QMenu(self)

        detail_menu = QAction('详情')
        detail_menu.triggered.connect(lambda: self.action_menu(index, 'detail'))
        menu.addAction(detail_menu)

        remove_menu = QAction('卸下')
        remove_menu.triggered.connect(lambda: self.action_menu(index, 'uninstall'))
        menu.addAction(remove_menu)

        install_menu = QAction('安装')
        install_menu.triggered.connect(lambda: self.action_menu(index, 'install'))
        menu.addAction(install_menu)

        menu.exec(self.viewport().mapToGlobal(position))

    def action_menu(self, index, mode):
        i = index.row()
        equip: Equipment = self.player.equip_slots[EQUIPMENT_SLOTS[i]]

        if mode == 'detail':
            if equip is not None:
                open_window('equip_detail', equip)
        elif mode == 'install':
            equip_list = []
            for equip in self.player.bag.equipment:
                # 过滤掉不属于该槽位的装备
                if equip.slot != EQUIPMENT_SLOTS[i]:
                    continue

                equip_list.append(equip)
            if equip_list:
                open_window('dialog_list_equip', equip_list, self.player)
            else:
                message_box_information('没有该部位的其他装备')
        elif mode == 'uninstall':
            if not equip:
                return
            equip.uninstall(self.player)
            self.setItem(i, 1, QTableWidgetItem())

            SIGNALS.update_player_penal.emit()
            SIGNALS.update_equip_table.emit()
            SIGNALS.update_bag.emit()
            self.update_data()
        else:
            return
